// 简单实现
function memoize(fn) {
    const cache = new Map();
    return function (...args) {
        const key = JSON.stringify(args);
        if (cache.has(key)) {
            return cache.get(key);
        }
        const result = fn.apply(this, args);
        cache.set(key, result);
        return result;
    }
}

// 带缓存控制的实现
function memoizeWithOptions(fn, options = {}) {
    let { maxSize = 100, ttl = null } = options;
    const cache = new Map();
    const timeStamp = new Map();

    return function (...args) {
        const key = JSON.stringify(args);
        const now = Date.now();

        // 检查缓存是否存在且未过期
        if (cache.has(key)) {
            if (ttl && now - timeStamp.get(key) < ttl) {
                return cache.get(key);
            }
            cache.delete(key);
            timeStamp.delete(key);
        }

        // 清理过期的缓存
        if (ttl) {
            for (const [cacheKey, timestamp] of timeStamp) {
                if (now - timestamp > ttl) {
                    cache.delete(cacheKey);
                    timeStamp.delete(cacheKey);
                }
            }
        }

        // 控制缓存的大小
        if (cache.size >= maxSize) {
            const firstKey = cache.keys().next().value;
            cache.delete(firstKey);
            timeStamp.delete(firstKey);
        }

        // 执行函数并缓存结果
        const result = fn.apply(this, args);
        cache.set(key, result);
        timeStamp.set(key, now);
        return result;
    }
}

// 测试案例
console.log('=== 测试简单记忆化函数 ===');

// 测试1: 简单计算函数
function expensiveCalculation(n) {
    console.log(`计算 ${n} 的平方...`);
    return n * n;
}

const memoizedCalc = memoize(expensiveCalculation);

console.log('第一次调用:', memoizedCalc(5)); // 应该打印"计算 5 的平方..."
console.log('第二次调用:', memoizedCalc(5)); // 应该直接返回结果，不打印
console.log('不同参数调用:', memoizedCalc(10)); // 应该打印"计算 10 的平方..."

// 测试2: 斐波那契数列
function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

const memoizedFib = memoize(fibonacci);
console.log('斐波那契(10):', memoizedFib(10));

console.log('=== 测试带缓存控制的记忆化函数 ===');

// 测试3: 带缓存控制的函数
function slowFunction(x) {
    console.log(`执行慢函数，参数: ${x}`);
    return x * 2;
}

const controlledMemoize = memoizeWithOptions(slowFunction, {
    maxSize: 2,
    ttl: 1000 // 1秒过期
});

console.log('第一次调用:', controlledMemoize(1));
console.log('第二次调用:', controlledMemoize(1)); // 应该从缓存获取
console.log('新参数调用:', controlledMemoize(2));
console.log('另一个新参数调用:', controlledMemoize(3)); // 应该触发缓存清理

// 测试4: 测试缓存过期
setTimeout(() => {
    console.log('1秒后再次调用:', controlledMemoize(1)); // 应该重新计算
}, 1100);

// 测试5: 对象参数
function processObject(obj) {
    console.log('处理对象:', obj);
    return Object.keys(obj).length;
}

const memoizedObj = memoize(processObject);
const testObj = { a: 1, b: 2 };
console.log('对象参数测试1:', memoizedObj(testObj));
console.log('对象参数测试2:', memoizedObj(testObj)); // 应该从缓存获取

console.log('=== 测试完成 ===');